/*
 * presentation.c : uRobot UPnP Presentation Page.
 * Originally developped for the uRobot project.
 * Copyright (C) 2011-2012 Seong-Woo Kim <libero@deu.ac.kr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if HAVE_LANGINFO_CODESET
# include <langinfo.h>
#endif

#include "config.h"
#include "buffer.h"
#include "presentation.h"
#include "gettext.h"
#include "cam.h"
#include "target.h"

#define CGI_ACTION "action="
#define CGI_ACTION_REFRESH "refresh"
#define CGI_MCS_ACTION_GO_FORWARD "GoForward"
#define CGI_MCS_ACTION_GO_BACKWARD "GoBackward"
#define CGI_MCS_ACTION_STOP "Stop"
#define CGI_MCS_ACTION_TURN_LEFT "TurnLeft"
#define CGI_MCS_ACTION_TURN_RIGHT "TurnRight"
#define CGI_SMS_ACTION_SET_FRONT_LIGHT "FrontLight"
#define CGI_SMS_ACTION_SET_FOG_LIGHT "FogLight"
#define CGI_SMS_ACTION_SET_BREAK_LIGHT "BreakLight"
#define CGI_SMS_ACTION_SET_WINKER_LIGHT "WinkerLight"
#define CGI_SMS_ACTION_GET_DISTANCES "GetDistances"
#define CGI_SMS_LABEL_FRONT_DISTANCE	 "Front"
#define CGI_SMS_LABEL_BACK_DISTANCE	 "Back"
#define CGI_SMS_LABEL_LEFT_DISTANCE	 "Left"
#define CGI_SMS_LABEL_RIGHT_DISTANCE	 "Right"
#define CGI_PATH "path"
#define CGI_SHARE "share"

#define UTF8 "UTF-8"

int
process_cgi (struct urobot_t *ut, char *cgiargs)
{
  char *action = NULL;
  int refresh = 0;
  int result = 0;

  if (!ut || !cgiargs)
    return -1;

  if (strncmp (cgiargs, CGI_ACTION, strlen (CGI_ACTION)))
    return -1;

  action = cgiargs + strlen (CGI_ACTION);

  if (!strncmp (action, CGI_MCS_ACTION_GO_FORWARD, strlen (CGI_MCS_ACTION_GO_FORWARD))) {
    result = set_motion(FORWARD_MOTION, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    buffer_appendf (ut->presentation, "<result>%s command was completed.</result>", CGI_MCS_ACTION_GO_FORWARD);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_MCS_ACTION_GO_BACKWARD, strlen (CGI_MCS_ACTION_GO_BACKWARD))) {
    result = set_motion(BACKWARD_MOTION, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    buffer_appendf (ut->presentation, "<result>%s command was completed.</result>", CGI_MCS_ACTION_GO_BACKWARD);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_MCS_ACTION_STOP, strlen (CGI_MCS_ACTION_STOP))) {
    result = set_motion(STOP_MOTION, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    buffer_appendf (ut->presentation, "<result>%s command was completed.</result>", CGI_MCS_ACTION_STOP);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_MCS_ACTION_TURN_LEFT, strlen (CGI_MCS_ACTION_TURN_LEFT))) {
    result = set_motion(LEFTTURN_MOTION, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    buffer_appendf (ut->presentation, "<result>%s command was completed.</result>", CGI_MCS_ACTION_TURN_LEFT);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_MCS_ACTION_TURN_RIGHT, strlen (CGI_MCS_ACTION_TURN_RIGHT))) {
    result = set_motion(RIGHTTURN_MOTION, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    buffer_appendf (ut->presentation, "<result>%s command was completed.</result>", CGI_MCS_ACTION_TURN_RIGHT);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_SMS_ACTION_SET_FRONT_LIGHT, strlen (CGI_SMS_ACTION_SET_FRONT_LIGHT))) {
    result = set_sensor_data(LIGHT_SENSOR, FRONT_LIGHT_SENSOR, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    if (result == 0)
      buffer_appendf (ut->presentation, "<result>%s was turned off.</result>", CGI_SMS_ACTION_SET_FRONT_LIGHT);
    else
      buffer_appendf (ut->presentation, "<result>%s was turned on.</result>", CGI_SMS_ACTION_SET_FRONT_LIGHT);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_SMS_ACTION_SET_FOG_LIGHT, strlen (CGI_SMS_ACTION_SET_FOG_LIGHT))) {
    result = set_sensor_data(LIGHT_SENSOR, FOG_LIGHT_SENSOR, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    if (result == 0)
      buffer_appendf (ut->presentation, "<result>%s was turned off.</result>", CGI_SMS_ACTION_SET_FOG_LIGHT);
    else
      buffer_appendf (ut->presentation, "<result>%s was turned on.</result>", CGI_SMS_ACTION_SET_FOG_LIGHT);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_SMS_ACTION_SET_BREAK_LIGHT, strlen (CGI_SMS_ACTION_SET_BREAK_LIGHT))) {
    result = set_sensor_data(LIGHT_SENSOR, BREAK_LIGHT_SENSOR, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    if (result == 0)
      buffer_appendf (ut->presentation, "<result>%s was turned off.</result>", CGI_SMS_ACTION_SET_BREAK_LIGHT);
    else
      buffer_appendf (ut->presentation, "<result>%s was turned on.</result>", CGI_SMS_ACTION_SET_BREAK_LIGHT);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_SMS_ACTION_SET_WINKER_LIGHT, strlen (CGI_SMS_ACTION_SET_WINKER_LIGHT))) {
    result = set_sensor_data(LIGHT_SENSOR, WINKER_LIGHT_SENSOR, 0);
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    buffer_append (ut->presentation, "<response>");
    if (result == 0)
      buffer_appendf (ut->presentation, "<result>%s was turned off.</result>", CGI_SMS_ACTION_SET_WINKER_LIGHT);
    else
      buffer_appendf (ut->presentation, "<result>%s was turned on.</result>", CGI_SMS_ACTION_SET_WINKER_LIGHT);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_SMS_ACTION_GET_DISTANCES, strlen (CGI_SMS_ACTION_GET_DISTANCES))) {
    unsigned short data[5];
    if (ut->presentation)
      buffer_free (ut->presentation);
    ut->presentation = buffer_new ();

    get_sensor_data(DISTANCE_SENSOR, data);
    buffer_append (ut->presentation, "<response>");
    buffer_appendf (ut->presentation, "<result>%d</result>", data[0]);
    buffer_appendf (ut->presentation, "<result>%d</result>", data[1]);
    buffer_appendf (ut->presentation, "<result>%d</result>", data[2]);
    buffer_appendf (ut->presentation, "<result>%d</result>", data[3]);
    buffer_append (ut->presentation, "</response>");
    return 1;
  }
  else if (!strncmp (action, CGI_ACTION_REFRESH, strlen (CGI_ACTION_REFRESH)))
    refresh = 1;

  if (ut->presentation)
    buffer_free (ut->presentation);
  ut->presentation = buffer_new ();

  buffer_append (ut->presentation, "<html>");
  buffer_append (ut->presentation, "<head>");
  buffer_appendf (ut->presentation, "<title>%s</title>",
                  _("uRobot Information Page"));
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"pragma\" content=\"no-cache\"/>");
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"expires\" content=\"1970-01-01\"/>");
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"refresh\" content=\"0; URL=/web/urobot.html\"/>");
  buffer_append (ut->presentation, "</head>");
  buffer_append (ut->presentation, "</html>");

  return 0;
}

void
build_javascript (struct urobot_t *ut)
{
  struct buffer_t *cam = NULL;

  buffer_append (ut->presentation, "<script type=\"text/javascript\">");
  buffer_append (ut->presentation, "function createXMLHttpRequest() {");
  buffer_append (ut->presentation, "  if (window.ActiveXObject) {");
  buffer_append (ut->presentation, "    xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");");
  buffer_append (ut->presentation, "  }");
  buffer_append (ut->presentation, "  else if (window.XMLHttpRequest) {");
  buffer_append (ut->presentation, "    xmlHttp = new XMLHttpRequest();");
  buffer_append (ut->presentation, "  }");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function e(el) {");
  buffer_append (ut->presentation, "  d = document;");
  buffer_append (ut->presentation, "  if(d.getElementById) {");
  buffer_append (ut->presentation, "    return d.getElementById(el);");
  buffer_append (ut->presentation, "  } else if (d.all) {");
  buffer_append (ut->presentation, "    return d.all[el];");
  buffer_append (ut->presentation, "  }");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function motion(action) {");
  buffer_append (ut->presentation, "  createXMLHttpRequest();");
  buffer_appendf (ut->presentation, "  var url = \"%s?action=\"+action;",
				   UROBOT_CGI);
  buffer_append (ut->presentation, "  xmlHttp.open(\"GET\", url, true);");
  buffer_append (ut->presentation, "  xmlHttp.onreadystatechange = motionCallback;");
  buffer_append (ut->presentation, "  xmlHttp.send(null);");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function motionCallback() {");
  buffer_append (ut->presentation, "  if (xmlHttp.readyState == 4) {");
  buffer_append (ut->presentation, "    if (xmlHttp.status == 200) {");
  buffer_append (ut->presentation, "      var result = xmlHttp.responseXML.getElementsByTagName(\"result\")[0].firstChild.data;");
  buffer_append (ut->presentation, "      e('motion').innerHTML = result;");

  buffer_append (ut->presentation, "    }");
  buffer_append (ut->presentation, "  }");
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function motion_f() {");
  buffer_appendf (ut->presentation, "  motion('%s');", CGI_MCS_ACTION_GO_FORWARD);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function motion_b() {");
  buffer_appendf (ut->presentation, "  motion('%s');", CGI_MCS_ACTION_GO_BACKWARD);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function motion_s() {");
  buffer_appendf (ut->presentation, "  motion('%s');", CGI_MCS_ACTION_STOP);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function motion_l() {");
  buffer_appendf (ut->presentation, "  motion('%s');", CGI_MCS_ACTION_TURN_LEFT);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function motion_r() {");
  buffer_appendf (ut->presentation, "  motion('%s');", CGI_MCS_ACTION_TURN_RIGHT);
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function sensor(action) {");
  buffer_append (ut->presentation, "  createXMLHttpRequest();");
  buffer_appendf (ut->presentation, "  var url = \"%s?action=\"+action;",
				   UROBOT_CGI);
  buffer_append (ut->presentation, "  xmlHttp.open(\"GET\", url, true);");
  buffer_append (ut->presentation, "  xmlHttp.onreadystatechange = sensorCallback;");
  buffer_append (ut->presentation, "  xmlHttp.send(null);");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function sensorCallback() {");
  buffer_append (ut->presentation, "  if (xmlHttp.readyState == 4) {");
  buffer_append (ut->presentation, "    if (xmlHttp.status == 200) {");
  buffer_append (ut->presentation, "      var result = xmlHttp.responseXML.getElementsByTagName(\"result\")[0].firstChild.data;");
  buffer_append (ut->presentation, "      e('sensor').innerHTML = result;");

  buffer_append (ut->presentation, "    }");
  buffer_append (ut->presentation, "  }");
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function sensor_fr() {");
  buffer_appendf (ut->presentation, "  sensor('%s');", CGI_SMS_ACTION_SET_FRONT_LIGHT);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function sensor_fg() {");
  buffer_appendf (ut->presentation, "  sensor('%s');", CGI_SMS_ACTION_SET_FOG_LIGHT);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function sensor_br() {");
  buffer_appendf (ut->presentation, "  sensor('%s');", CGI_SMS_ACTION_SET_BREAK_LIGHT);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function sensor_wk() {");
  buffer_appendf (ut->presentation, "  sensor('%s');", CGI_SMS_ACTION_SET_WINKER_LIGHT);
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function poll() {");
  buffer_append (ut->presentation, "  createXMLHttpRequest();");
  buffer_appendf (ut->presentation, "  var url = \"%s?action=%s\";",
				   UROBOT_CGI, CGI_SMS_ACTION_GET_DISTANCES);
  buffer_append (ut->presentation, "  xmlHttp.open(\"GET\", url, true);");
  buffer_append (ut->presentation, "  xmlHttp.onreadystatechange = pollCallback;");
  buffer_append (ut->presentation, "  xmlHttp.send(null);");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function pollCallback() {");
  buffer_append (ut->presentation, "  if (xmlHttp.readyState == 4) {");
  buffer_append (ut->presentation, "    if (xmlHttp.status == 200) {");
  buffer_append (ut->presentation, "      var result1 = xmlHttp.responseXML.getElementsByTagName(\"result\")[0].firstChild.data;");
  buffer_append (ut->presentation, "      var result2 = xmlHttp.responseXML.getElementsByTagName(\"result\")[1].firstChild.data;");
  buffer_append (ut->presentation, "      var result3 = xmlHttp.responseXML.getElementsByTagName(\"result\")[2].firstChild.data;");
  buffer_append (ut->presentation, "      var result4 = xmlHttp.responseXML.getElementsByTagName(\"result\")[3].firstChild.data;");
  buffer_append (ut->presentation, "      fd(parseInt(result1));");
  buffer_append (ut->presentation, "      bd(parseInt(result2));");
  buffer_append (ut->presentation, "      ld(parseInt(result3));");
  buffer_append (ut->presentation, "      rd(parseInt(result4));");
  buffer_append (ut->presentation, "      setTimeout(\"poll()\", 1000);");
  buffer_append (ut->presentation, "    }");
  buffer_append (ut->presentation, "  }");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "function s(el,n,max,text) {");
  buffer_append (ut->presentation, "  e(el).innerHTML = '<table width=354 border=0 cellpadding=1 cellspacing=0>'+");
  buffer_append (ut->presentation, "                    '<tr><td width=150>' +");
  buffer_append (ut->presentation, "                    text + '</td>' +");
  buffer_append (ut->presentation, "                    '<td width=' + (200*n/max) + ' bgcolor=\"gray\">&nbsp;</td>' +");
  buffer_append (ut->presentation, "                    '<td width=' + (200-200*n/max) + ' bgcolor=\"lightgray\">&nbsp;</td>' +");
  buffer_append (ut->presentation, "                    '</table>';");
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function dc(n,d) {");
  buffer_append (ut->presentation, "  return n.toFixed(d);");
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function fd(m) {");
  buffer_append (ut->presentation, "  n = dc(m, 1);");
  buffer_appendf (ut->presentation, "  s('%s',n,1000,'%s '+n+' meter');", CGI_SMS_LABEL_FRONT_DISTANCE, CGI_SMS_LABEL_FRONT_DISTANCE);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function bd(m) {");
  buffer_append (ut->presentation, "  n = dc(m, 1);");
  buffer_appendf (ut->presentation, "  s('%s',n,1000,'%s '+n+' meter');", CGI_SMS_LABEL_BACK_DISTANCE, CGI_SMS_LABEL_BACK_DISTANCE);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function ld(m) {");
  buffer_append (ut->presentation, "  n = dc(m, 1);");
  buffer_appendf (ut->presentation, "  s('%s',n,1000,'%s '+n+' meter');", CGI_SMS_LABEL_LEFT_DISTANCE, CGI_SMS_LABEL_LEFT_DISTANCE);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function rd(m) {");
  buffer_append (ut->presentation, "  n = dc(m, 1);");
  buffer_appendf (ut->presentation, "  s('%s',n,1000,'%s '+n+' meter');", CGI_SMS_LABEL_RIGHT_DISTANCE, CGI_SMS_LABEL_RIGHT_DISTANCE);
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function i(n) {");
  buffer_append (ut->presentation, "  e('i').innerHTML = n;");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "var imageNr = 0;");
  buffer_append (ut->presentation, "var finished = new Array();");
  buffer_append (ut->presentation, "var paused = false;");
  buffer_append (ut->presentation, "function createImageLayer() {");
  buffer_append (ut->presentation, "  var img = new Image();");
  buffer_append (ut->presentation, "  img.style.position = \"absolute\";");
  buffer_append (ut->presentation, "  img.style.zIndex = -1;");
  buffer_append (ut->presentation, "  img.onload = imageOnload;");
  buffer_append (ut->presentation, "  img.onclick = imageOnclick;");
  cam = buffer_new ();
  cam_browse_metadata (cam, 0, 1/*0*/);
  buffer_appendf (ut->presentation, "  img.src = \"%s&n=\" + (++imageNr);", cam->buf);
  buffer_free (cam);
  buffer_append (ut->presentation, "  var webcam = e('webcam');");
  buffer_append (ut->presentation, "  webcam.insertBefore(img, webcam.firstChild);");
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function imageOnload() {");
  buffer_append (ut->presentation, "  this.style.zIndex = imageNr;");

  buffer_append (ut->presentation, "  while (1 < finished.length) {");
  buffer_append (ut->presentation, "    var del = finished.shift();");
  buffer_append (ut->presentation, "    del.parentNode.removeChild(del);");
  buffer_append (ut->presentation, "  }");

  buffer_append (ut->presentation, "  finished.push(this);");
  buffer_append (ut->presentation, "  if (!paused) createImageLayer();");
  buffer_append (ut->presentation, "}");
  buffer_append (ut->presentation, "function imageOnclick() {");
  buffer_append (ut->presentation, "  paused = !paused;");
  buffer_append (ut->presentation, "  if (!paused) createImageLayer();");
  buffer_append (ut->presentation, "}");

  buffer_append (ut->presentation, "</script>");
}

int
build_presentation_page (struct urobot_t *ut)
{
  char *mycodeset = NULL;
  struct buffer_t *cam = NULL;

  if (!ut)
    return -1;

  if (ut->presentation)
    buffer_free (ut->presentation);
  ut->presentation = buffer_new ();

#if HAVE_LANGINFO_CODESET
  mycodeset = nl_langinfo (CODESET);
#endif
  if (!mycodeset)
    mycodeset = UTF8;

  buffer_append (ut->presentation, "<html>");
  buffer_append (ut->presentation, "<head>");
  buffer_appendf (ut->presentation, "<title>%s</title>",
                 _("uRobot Information Page"));
  buffer_appendf (ut->presentation,
                  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>",
                  mycodeset);
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"pragma\" content=\"no-cache\"/>");
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"expires\" content=\"1970-01-01\"/>");

  build_javascript (ut);

  buffer_append (ut->presentation, "</head>");

  //buffer_append (ut->presentation, "<body>");
  buffer_append (ut->presentation, "<body onload=\"createImageLayer();\">");
  buffer_append (ut->presentation, "<h1 align=\"center\">");
  buffer_appendf (ut->presentation, "<tt>%s</tt><br/>",
                  _("uRobot UPnP Robot Server"));
  buffer_append (ut->presentation, _("Information Page"));
  buffer_append (ut->presentation, "</h1>");
  buffer_append (ut->presentation, "<br/>");

  buffer_append (ut->presentation, "<center>");
  buffer_append (ut->presentation, "<tr width=\"500\">");
  buffer_appendf (ut->presentation, "<b>%s :</b> %s<br/>",
                  _("Version"), VERSION);
  buffer_append (ut->presentation, "</tr>");
  buffer_appendf (ut->presentation, "<b>%s :</b> %s<br/>",
                  _("Device UDN"), ut->udn);
  buffer_append (ut->presentation, "</center><br/>");

  buffer_append (ut->presentation, "<b>Motion Control</b><br/>");

  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"motion_f();\"/>", CGI_MCS_ACTION_GO_FORWARD, CGI_MCS_ACTION_GO_FORWARD);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"motion_b();\"/>", CGI_MCS_ACTION_GO_BACKWARD, CGI_MCS_ACTION_GO_BACKWARD);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"motion_s();\"/>", CGI_MCS_ACTION_STOP, CGI_MCS_ACTION_STOP);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"motion_l();\"/>", CGI_MCS_ACTION_TURN_LEFT, CGI_MCS_ACTION_TURN_LEFT);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"motion_r();\"/>", CGI_MCS_ACTION_TURN_RIGHT, CGI_MCS_ACTION_TURN_RIGHT);
  buffer_append (ut->presentation, "<br/>");
  buffer_append (ut->presentation, "<div id=\"motion\"></div>");
/*
  buffer_appendf (ut->presentation,
                  "<form method=\"get\" action=\"%s\">", UROBOT_CGI);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_MCS_ACTION_GO_FORWARD);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_MCS_ACTION_GO_BACKWARD);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_MCS_ACTION_STOP);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_MCS_ACTION_TURN_LEFT);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_MCS_ACTION_TURN_RIGHT);
  buffer_append (ut->presentation, "</form>");
*/
  buffer_append (ut->presentation, "<br/>");

  buffer_append (ut->presentation, "<b>Sensor Control</b><br/>");
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"sensor_fr();\"/>", CGI_SMS_ACTION_SET_FRONT_LIGHT, CGI_SMS_ACTION_SET_FRONT_LIGHT);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"sensor_fg();\"/>", CGI_SMS_ACTION_SET_FOG_LIGHT, CGI_SMS_ACTION_SET_FOG_LIGHT);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"sensor_br();\"/>", CGI_SMS_ACTION_SET_BREAK_LIGHT, CGI_SMS_ACTION_SET_BREAK_LIGHT);
  buffer_appendf (ut->presentation, "<input type=\"button\" value=\"%s\" id=\"%s\" onclick=\"sensor_wk();\"/>", CGI_SMS_ACTION_SET_WINKER_LIGHT, CGI_SMS_ACTION_SET_WINKER_LIGHT);
  buffer_append (ut->presentation, "<br/>");
  buffer_append (ut->presentation, "<div id=\"sensor\"></div>");
/*
  buffer_appendf (ut->presentation,
                  "<form method=\"get\" action=\"%s\">", UROBOT_CGI);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_SMS_ACTION_SET_FRONT_LIGHT);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_SMS_ACTION_SET_FOG_LIGHT);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_SMS_ACTION_SET_BREAK_LIGHT);
  buffer_appendf (ut->presentation,
                  "<input type=\"submit\" name=\"action\" value=\"%s\"/>",
                  CGI_SMS_ACTION_SET_WINKER_LIGHT);
  buffer_append (ut->presentation, "</form>");
*/
  buffer_append (ut->presentation, "<br/>");

  buffer_append (ut->presentation, "<b>Sensor Monitoring</b><br/>");
  buffer_appendf (ut->presentation,
                  "<input type=\"button\" value=\"Start\" name=\"Start\" id=\"start\" onclick=\"poll()\"/>");
 buffer_appendf (ut->presentation, "<div id=\"%s\"></div>", CGI_SMS_LABEL_FRONT_DISTANCE);
 buffer_appendf (ut->presentation, "<div id=\"%s\"></div>", CGI_SMS_LABEL_BACK_DISTANCE);
 buffer_appendf (ut->presentation, "<div id=\"%s\"></div>", CGI_SMS_LABEL_LEFT_DISTANCE);
 buffer_appendf (ut->presentation, "<div id=\"%s\"></div>", CGI_SMS_LABEL_RIGHT_DISTANCE);

/*
<!--script type="text/javascript">fd(10);</script-->
<!--script type="text/javascript">bd(30);</script-->
<!--script type="text/javascript">ld(50);</script-->
<!--script type="text/javascript">rd(70);</script-->
*/
  buffer_append (ut->presentation, "<br/>");
  buffer_append (ut->presentation, "<b>Camera Monitoring</b><br/>");

  cam = buffer_new ();
  cam_browse_metadata (cam, 0, 1/*0*/);
  //buffer_appendf (ut->presentation, "<img src=\"%s\" width=\"320\" height=\"240\" />", cam->buf);
  buffer_appendf (ut->presentation, "<div id=\"webcam\"><noscript><img src=\"%s\" width=\"320\" height=\"240\" /></noscript></div>", cam->buf);
  printf("cambuf=%s\n", cam->buf);
  buffer_free (cam);
  buffer_append (ut->presentation, "<br/>");

  buffer_appendf (ut->presentation,
                  "<form method=\"get\" action=\"%s\">", UROBOT_CGI);
  buffer_appendf (ut->presentation,
                  "<input type=\"hidden\" name=\"action\" value=\"%s\"/>",
                  CGI_ACTION_REFRESH);
  buffer_appendf (ut->presentation, "<input type=\"submit\" value=\"%s\"/>",
                  _("Refresh ..."));
  buffer_append (ut->presentation, "</form>");

  buffer_append (ut->presentation, "</body>");
  buffer_append (ut->presentation, "</html>");

  return 0;
}
